|
ARD2
RC2
Airbag Reference Demonstrator using MPC5604P
|
00001 00017 #include "derivative.h" 00018 #include "PIT.h" 00019 #include "eDMA.h" 00020 #include "MailDelivery.h" 00021 #include "MailScheduler.h" 00022 /* TEMP ERASE AFTER DEBUG */ 00023 #include "Compile_options.h" 00024 /* 00025 ****************************************************************************** 00026 * Constants 00027 ****************************************************************************** 00028 */ 00029 /* 00030 ****************************************************************************** 00031 * Globals 00032 ****************************************************************************** 00033 */ 00034 vuint32_t gu32SchedTickCount; 00035 vuint32_t gu32SchedTxDoneCount; 00036 vuint8_t gu8RescheduleSource; 00037 static uint32_t gu32SchedPITCount; 00038 uint8_t gu8ReSchPITCh; 00039 static uint8_t gu8SchedPITCh; 00040 static uint8_t gu8SchedWriting; 00041 /* 00042 ****************************************************************************** 00043 * u8fnSchedConfig 00044 ****************************************************************************** 00045 */ 00046 uint8_t u8fnSchedConfig(uint32_t u32PITCnt, uint8_t u8PITCh, 00047 uint32_t u32ReSchCnt, uint8_t u8ReSchPITCh) 00048 { 00049 uint8_t u8Status; 00050 00051 u8Status = CLEAR; 00052 00053 /* Start by stopping any PIT count */ 00054 vfnPITStart(u8PITCh, CLEAR); 00055 vfnPITStart(u8ReSchPITCh, CLEAR); 00056 00057 /* Configure PIT for a periodical wake-up with ISRs need to switch mailboxes */ 00058 u8Status = u8fnPITConfig(u8PITCh, u32PITCnt, TRUE); 00059 00060 /* Prepare the Rescheduling channel as well */ 00061 u8Status |= u8fnPITConfig(u8ReSchPITCh, u32ReSchCnt, TRUE); 00062 00063 /* Continue only if successful */ 00064 if(CLEAR == u8Status) 00065 { 00066 /* Restart whatever count we had before */ 00067 gu32SchedTickCount = CLEAR; 00068 00069 /* Remember the passed variables in our globals */ 00070 gu32SchedPITCount = u32PITCnt; 00071 gu8SchedPITCh = u8PITCh; 00072 gu8ReSchPITCh = u8ReSchPITCh; 00073 } 00074 else 00075 { 00076 /* Nothing */ 00077 } 00078 return (u8Status); 00079 } 00080 /* 00081 ****************************************************************************** 00082 * u8fnSchedEnable 00083 ****************************************************************************** 00084 */ 00085 uint8_t u8fnSchedEnable(uint8_t u8Enable) 00086 { 00087 vfnPITStart(gu8SchedPITCh, u8Enable); 00088 00089 /* We're starting - we need to init our writing permission */ 00090 gu8SchedWriting = MAILBOX_WRITING_ALLOWED; 00091 00092 return (CLEAR); 00093 } 00094 /* 00095 ****************************************************************************** 00096 * u8fnSchedDSPIMailTransfer 00097 ****************************************************************************** 00098 */ 00099 uint8_t u8fnSchedDSPIMailTransfer(uint8_t u8DSPIInstance, 00100 uint8_t u8CS, 00101 uint8_t u8ContCS, 00102 uint8_t u8EndOfQueueFlag, 00103 uint16_t* pu16MsgSrc, 00104 uint16_t* pu16MsgResponse, 00105 uint16_t u16Size) 00106 { 00107 uint8_t u8Status; 00108 00109 u8Status = MAILBOX_IS_BEING_WRITTEN; 00110 00111 /* First, verify we can write */ 00112 if(MAILBOX_WRITING_ALLOWED == gu8SchedWriting) 00113 { 00114 /* Lock */ 00115 gu8SchedWriting = MAILBOX_WRITING_PROHIBITED; 00116 00117 /* Start by appending the message to the outbox */ 00118 u8Status = u8fnMailboxAppendToDSPIOutbox(u8DSPIInstance, u8CS, u8ContCS, 00119 u8EndOfQueueFlag, pu16MsgSrc, 00120 u16Size); 00121 if(CLEAR == u8Status) 00122 { 00123 /* Continue by preparing the pointer to the right location once we're done */ 00124 u8Status = u8fnMailboxAppendToInbox(pu16MsgResponse, u16Size); 00125 } 00126 else 00127 { 00128 /* nothing, it's been taken care of */ 00129 } 00130 00131 /* Unlock */ 00132 gu8SchedWriting = MAILBOX_WRITING_ALLOWED; 00133 } 00134 else 00135 { 00136 /* nothing, it's been taken care of */ 00137 } 00138 return (u8Status); 00139 } 00140 /* 00141 ****************************************************************************** 00142 * u8fnSchedCompositeDSPIMailTransfer 00143 ****************************************************************************** 00144 */ 00145 uint8_t u8fnSchedCompositeDSPIMailTransfer(const uint8_t u8DSPIInstance1, 00146 const uint8_t u8DSPIInstance2, 00147 const uint8_t u8CS, 00148 uint16_t* pu16MsgSrc1, 00149 uint16_t* pu16MsgSrc2, 00150 const uint16_t* pu16MsgResponse, 00151 uint16_t u16SizeAtOrigin) 00152 { 00153 uint8_t u8Status; 00154 uint16_t u16SizeAtDestination; 00155 uint16_t u16LastBufferAddress; 00156 00157 #ifdef DEBUGGING_NOW 00158 // SIU.GPDO[9].B.PDO = 1; 00159 #endif 00160 u8Status = CLEAR; 00161 u16SizeAtDestination = u16SizeAtOrigin * 2u; 00162 00163 /* First, verify we can write */ 00164 if(MAILBOX_WRITING_ALLOWED == gu8SchedWriting) 00165 { 00166 /* Check that our outbox buffer size is capable of handling the message */ 00167 if(gu8MailboxActiveOutboxOffset < OUTBOX_ACTIVE_OUTBOX_IS_2) 00168 { 00169 u16LastBufferAddress = (uint16_t)gu8MailboxActiveOutboxOffset 00170 + u16SizeAtDestination; 00171 } 00172 else 00173 { 00174 u16LastBufferAddress = (uint16_t)gu8MailboxActiveOutboxOffset 00175 + u16SizeAtDestination - OUTBOX_ACTIVE_OUTBOX_IS_2; 00176 } 00177 /* Only continue if we can complete the transaction */ 00178 if(OUTBOX_MAX_BUFFER_CNT > u16LastBufferAddress) 00179 { 00180 00181 /* Lock */ 00182 gu8SchedWriting = MAILBOX_WRITING_PROHIBITED; 00183 00184 /* What we want to do is send a complex message based out of two CITER */ 00185 /* locations. We will prepare our outbox to do so by combining messages*/ 00186 /* Status will always be clear because otherwise we wouln't have */ 00187 /* gotten into this if case */ 00188 (void)u8fnMailboxAppendToCompositeDSPIOutbox(u8DSPIInstance1, 00189 u8DSPIInstance2, u8CS, 00190 pu16MsgSrc1, pu16MsgSrc2, 00191 u16SizeAtOrigin); 00192 00193 /* Continue by preparing the pointer to the right location once we're done */ 00194 u8Status 00195 = u8fnMailboxAppendToInbox(pu16MsgResponse, u16SizeAtDestination); 00196 00197 /* Unlock */ 00198 gu8SchedWriting = MAILBOX_WRITING_ALLOWED; 00199 } 00200 else 00201 { 00202 u8Status = MAILBOX_CAPACITY_HAS_BEEN_REACHED; 00203 } 00204 } 00205 else 00206 { 00207 u8Status = MAILBOX_IS_BEING_WRITTEN; 00208 } 00209 #ifdef DEBUGGING_NOW 00210 // SIU.GPDO[9].B.PDO = 0; 00211 #endif 00212 00213 return (u8Status); 00214 } 00215 /* 00216 ****************************************************************************** 00217 * u32fnSchedHasTimeElapsed 00218 ****************************************************************************** 00219 */ 00220 uint32_t u32fnSchedHasTimeElapsed(uint32_t u32MyTickCount) 00221 { 00222 uint32_t u32TimeDifference; 00223 00224 /* Compare passed count with existing count */ 00225 if(u32MyTickCount <= gu32SchedTickCount) 00226 { 00227 u32TimeDifference = gu32SchedTickCount - u32MyTickCount; 00228 } 00229 else 00230 { 00231 /* We have over-ran the counter. Still, this means */ 00232 /* we're not in the same cycle. */ 00233 u32TimeDifference = TRUE; 00234 } 00235 return (u32TimeDifference); 00236 } 00237 /* 00238 ****************************************************************************** 00239 * u32fnSchedIsTxDone 00240 ****************************************************************************** 00241 */ 00242 uint32_t u32fnSchedIsTxDone(uint32_t u32MyTxTime) 00243 { 00244 uint32_t u32TimeDifference; 00245 00246 /* Compare passed count with existing count */ 00247 if(u32MyTxTime <= gu32SchedTxDoneCount) 00248 { 00249 u32TimeDifference = gu32SchedTxDoneCount - u32MyTxTime; 00250 } 00251 else 00252 { 00253 /* We have over-ran the counter. Still, this means */ 00254 /* we're not in the same cycle. */ 00255 u32TimeDifference = TRUE; 00256 } 00257 return (u32TimeDifference); 00258 } 00259 /* 00260 ****************************************************************************** 00261 * vfnSchedIsr 00262 ****************************************************************************** 00263 */ 00264 void vfnSchedIsr(void) 00265 { 00266 /* Count */ 00267 gu32SchedTickCount++; 00268 00269 /* Force a SW isr */ 00270 INTC.SSCIR[4].B.SET = TRUE; 00271 00272 /*Trigger the appropriate DMA only if we have data */ 00273 if((CLEAR != gau32DSPIOutbox[gu8MailboxActiveOutboxOffset]) 00274 && (MAILBOX_WRITING_ALLOWED == gu8SchedWriting) 00275 && (EDMA.TCD[gu8InactiveOutboxDMA].DONE == TRUE)) 00276 { 00277 /* Switch Inbox and Outbox */ 00278 vfnMailboxSwitchActiveMailboxes(); 00279 00280 vfnDMAMUXInit(gu8InactiveOutboxDMA, DMA_SOURCE_DSPI0_TX, CLEAR, TRUE); 00281 00282 /* Trigger outbox through empty SPI Tx buffer */ 00283 vfnMailDeliveryTriggerOutbox(gu8InactiveOutboxDMA, TRUE); 00284 00285 /* Trigger inbox as well */ 00286 EDMA.SERQR.R = gu8InactiveInboxDMA; 00287 } 00288 else 00289 { 00290 /* Don't trigger */ 00291 } 00292 00293 /* Clear flag that brought us here */ 00294 PIT_CLEAR_FLAG(gu8SchedPITCh); 00295 00296 return; 00297 } 00298 /* 00299 ****************************************************************************** 00300 * vfnSchedInboxDoneIsr 00301 ****************************************************************************** 00302 */ 00303 void vfnSchedInboxDoneIsr(void) 00304 { 00305 /* This fn should be called after receiving all data */ 00306 00307 /* Clear BITER; CITER will be copied to it at launch */ 00308 /* (just before becoming active) */ 00309 EDMA.TCD[gu8InactiveOutboxDMA].BITER = CLEAR; 00310 vfnDMAMUXInit(gu8InactiveOutboxDMA, CLEAR, CLEAR, CLEAR); 00311 vfnDMAMUXInit(gu8InactiveInboxDMA, CLEAR, CLEAR, CLEAR); 00312 vfnDMAMUXInit(gu8InboxDMA, DMA_SOURCE_DSPI0_RX, CLEAR, TRUE); 00313 EDMA.CERQR.R = gu8InactiveInboxDMA; 00314 00315 /* Once the outbox is empty, the DMA doesn't need to be triggered by */ 00316 /* an empty SPI. Disable any MUX to any channel. */ 00317 DMA_CLEAR_ISR_FLAG(gu8InactiveInboxDMA); 00318 // DMA_CLEAR_ISR_FLAG(gu8InboxDMA); 00319 00320 /* Force Software ISRs to call any driver routines associated with having */ 00321 /* mail delivered */ 00322 // INTC.SSCIR[SCHED_INBOX_DONE_SW_ISR_1].B.SET = TRUE; 00323 INTC.SSCIR[SCHED_INBOX_DONE_SW_ISR_2].B.SET = TRUE; 00324 INTC.SSCIR[SCHED_INBOX_DONE_SW_ISR_3].B.SET = TRUE; 00325 INTC.SSCIR[SCHED_INBOX_DONE_SW_ISR_4].B.SET = TRUE; 00326 00327 /* Increment the Isr count */ 00328 gu32SchedTxDoneCount = gu32SchedTickCount; 00329 00330 return; 00331 } 00332 /* 00333 ****************************************************************************** 00334 * vfnReschedulerIsr 00335 ****************************************************************************** 00336 */ 00337 void vfnReschedulerIsr(void) 00338 { 00339 /* Call appropriate channels */ 00340 INTC.SSCIR[SCHED_RESCHED_1].B.SET = 00341 ((gu8RescheduleSource & RESCH_SRC_1) > CLEAR); 00342 INTC.SSCIR[SCHED_RESCHED_2].B.SET = 00343 ((gu8RescheduleSource & RESCH_SRC_2) > CLEAR); 00344 INTC.SSCIR[SCHED_RESCHED_3].B.SET = 00345 ((gu8RescheduleSource & RESCH_SRC_3) > CLEAR); 00346 00347 if(gu8RescheduleSource == CLEAR) 00348 { 00349 /* End its life */ 00350 /* Reschedule. Ch. 1 is for this Isr */ 00351 vfnPITStart(gu8ReSchPITCh, CLEAR); 00352 } 00353 else 00354 { 00355 /* We will be back soon enough */ 00356 } 00357 00358 /* Clear Rescheduling flag */ 00359 PIT_CLEAR_FLAG(gu8ReSchPITCh); 00360 00361 return; 00362 } 00363 00364 /* 00365 ****************************************************************************** 00366 * 00367 * End of file. 00368 * 00369 ****************************************************************************** 00370 */